package com.leejxx.health.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.leejxx.health.dao.PermissionDao;
import com.leejxx.health.dao.RoleDao;
import com.leejxx.health.dao.UserDao;
import com.leejxx.health.entity.PageResult;
import com.leejxx.health.entity.QueryPageBean;
import com.leejxx.health.exception.BusinessRuntimeException;
import com.leejxx.health.pojo.Permission;
import com.leejxx.health.pojo.Role;
import com.leejxx.health.pojo.User;
import com.leejxx.health.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.transaction.annotation.Transactional;

import java.util.LinkedHashSet;
import java.util.List;

/**
 * @Author LeeJx
 * @ClassName UserServiceImpl
 * @Description TODO
 * @date 2020/12/29 16:52
 * @Version 1.0
 */
@Slf4j
@DubboService
public class UserServiceImpl implements UserService {

    @Autowired
    private UserDao userDao;
    @Autowired
    private RoleDao roleDao;
    @Autowired
    private PermissionDao permissionDao;

    @Override
    @Transactional
    public User findByUsername(String username) {
        User user = userDao.findByUsername(username);
        List<Role> roles = roleDao.findByUserId(user.getId());

        for (Role role : roles) {
            List<Permission> permissions = permissionDao.findByRoleId(role.getId());
            role.getPermissions().addAll(permissions);
        }
        user.getRoles().addAll(roles);
        return user;
    }

    @Override
    public PageResult findByPage(QueryPageBean queryPageBean) {
        PageHelper.startPage(queryPageBean.getCurrentPage(), queryPageBean.getPageSize());
        Page<User> page = userDao.findByCondition(queryPageBean.getQueryString());
        return new PageResult(page.getTotal(), page.getResult());
    }

    @Override
    public LinkedHashSet<Role> findAllRoles() {
        return roleDao.findAllRoles();
    }

    @Override
    @Transactional
    public void addUser(User user, List<Integer> roleIds) {
        if (null == user.getUsername()||null==user.getPassword()) {
            throw new BusinessRuntimeException("用户名或密码不能为空，请重新输入");
        } else {

            List<String> usernames = userDao.findAllUsername();
            for (String username : usernames) {
                if (user.getUsername().equals(username)) {
                    throw new BusinessRuntimeException("用户名已被使用，请重新输入");
                }
            }

            user.setPassword("{bcrypt}" + new BCryptPasswordEncoder().encode(user.getPassword()));
            userDao.addUser(user);
            Integer userId = userDao.findUserId(user.getUsername());
            if (null != roleIds && roleIds.size() > 0) {
                for (Integer roleId : roleIds) {
                    userDao.insertRoleIdByUserId(userId, roleId);
                }
            }
        }
    }

    @Override
    @Transactional
    public User findUserById(Integer userId) {
        User user = userDao.findUserByUserId(userId);
        LinkedHashSet<Role> allRoles = roleDao.findAllRoles();
        List<Integer> roleIds = userDao.findRoleIdByUserId(userId);

        user.setRoles(allRoles);
        user.setRoleIds(roleIds);

        return user;
    }

    @Override
    @Transactional
    public void edit(User user, List<Integer> roleIds) {
        if (null == user.getUsername()) {
            throw new BusinessRuntimeException("用户名不能为空，请重新输入");
        } else {
            Integer userId = user.getId();

            //查找所有用户名
            List<String> usernames = userDao.findAllUsername();
            //查找原来的用户名
            String oldUsername= userDao.findUserNameByUserId(userId);
            //如果用户名没有修改，排除需要修改的用户名
            if (user.getUsername().equals(oldUsername)) {
                usernames.remove(user.getUsername());
            }

            for (String username : usernames) {
                if (user.getUsername().equals(username)) {
                    throw new BusinessRuntimeException("用户名已被使用，请重新输入");
                }
            }

            userDao.editUser(user);
            if (null != roleIds && roleIds.size() > 0) {
                userDao.deleteRoleIdByUserId(userId);
                for (Integer roleId : roleIds) {
                    userDao.insertRoleIdByUserId(userId, roleId);
                }
            } else {
                userDao.deleteRoleIdByUserId(userId);
            }
        }
    }

    @Override
    @Transactional
    public void deleteById(Integer userId) {
        Long countOfRole = userDao.findCountOfRoleByUserId(userId);
        if (countOfRole > 0) {
            throw new BusinessRuntimeException("该角色下有绑定数据，无法删除");
        } else if (countOfRole == 0) {
            userDao.deleteUserByUserId(userId);
        }
    }

    @Override
    public String findUsernameByUserId(Integer userId) {
        return userDao.findUserNameByUserId(userId);
    }

    @Override
    public void editPassword(User user) {
        if (null == user.getPassword()) {
            throw new BusinessRuntimeException("密码不能为空，请重新输入");
        } else {
            Integer userId = userDao.findUserId(user.getUsername());
            user.setId(userId);
            user.setPassword("{bcrypt}" + new BCryptPasswordEncoder().encode(user.getPassword()));
            userDao.editPasswordByUserId(user);
        }
    }
}
